package analiseSintatica.Regras.Tipos;

import AnaliseLexicaFinal.EstruturaDeDados.LinkToken;
import analiseSemantica.Tipos.TipoSemantico;
import analiseSemantica.Tipos.TiposSemanticos;
import analiseSintatica.ErroSintaticoException;
import analiseSintatica.Regras.Regra;
import java.util.LinkedList;

/**
 *
 * @author aluno
 * @author amferraz (analise sintatica)
 */
public class RegraTipoPrimitivo extends Regra{

    protected static Regra instancia;

    protected String estrutura = "<tipo_primitivo> ::= char | int | float | boolean";

    /**
     * Construtor privado necessario ao singleton
     */
    private RegraTipoPrimitivo() {
    }

    /**
     * Retorna a unica instancia dessa classe.
     * @return
     */
    public static RegraTipoPrimitivo getInstance() {
        if (instancia == null) {
            instancia = new RegraTipoPrimitivo();
        }
        return (RegraTipoPrimitivo) instancia;
    }

    @Override
    public TiposSemanticos analisar(LinkedList<LinkToken> listaTokens) throws ErroSintaticoException {
        

        
       if ( (listaTokens.getFirst().getLexema().equals("char"))||
            (listaTokens.getFirst().getLexema().equals("int"))||
            (listaTokens.getFirst().getLexema().equals("float"))||
            (listaTokens.getFirst().getLexema().equals("boolean")) ){

           //os tipos semanticos de retorno
           TiposSemanticos tipos = new TiposSemanticos();
           tipos.addTipos(new TipoSemantico(listaTokens.getFirst().getLexema(), listaTokens.getFirst().getLinha()));

           //pra sintática funcionar beleza
           listaTokens.removeFirst();
           
           return tipos;
       }
       else{
           ErroSintaticoException e = new ErroSintaticoException();
           e.addErros("Tipo primitivo esperado antes do token "+listaTokens.getFirst().getLexema(), estrutura, listaTokens.getFirst().getLinha());
           throw e;
       }

    }

    @Override
    protected void setPrimeiro() {
        this.primeiro.add("char");
        this.primeiro.add("int");
        this.primeiro.add("float");
        this.primeiro.add("boolean");
    }
}
